﻿using System;
using System.Collections.Generic;
using System.Threading;
using EasyHook;
using MassPokerTool.Infrastructure.Hooking;
using MassPokerTool.Infrastructure.Hooking.Data;
using MassPokerTool.Infrastructure.Hooking.Target;

namespace MassPokerTool.Inject
{
    public class ProcessEntryPoint : IEntryPoint, IQueueableEntryPoint
    {
        private readonly MassPokerInterface _processInterface;

        public ProcessEntryPoint(RemoteHooking.IContext inContext, string inChannelName, IHooksProvider hooksProvider)
        {
            Queue = new Queue<IHookData>();
            _processInterface = RemoteHooking.IpcConnectClient<MassPokerInterface>(inChannelName);
        }

        public void Run(RemoteHooking.IContext inContext, string inChannelName, IHooksProvider hooksProvider)
        {
            try
            {
                _processInterface.ReportMessage("Installing in ... " + RemoteHooking.GetCurrentProcessId());
                HookManager.CreateHooks(hooksProvider, this);
            }
            catch (Exception ex)
            {
                _processInterface.ReportError(ex.ToString());
                return;
            }
            _processInterface.IsInstalled(RemoteHooking.GetCurrentProcessId());
            RemoteHooking.WakeUpProcess();

            try
            {
                while (_processInterface.Ping(RemoteHooking.GetCurrentProcessId()))
                {
                    Thread.Sleep(1000);
                    lock (Queue)
                    {
                        if (Queue.Count > 0)
                        {
                            foreach (var queueEntry in Queue)
                            {
                                _processInterface.Process(queueEntry);
                            }
                            Queue.Clear();
                        }
                    }
                }
            }
            catch(Exception e)
            {
                // Ping() will raise an exception if host is unreachable
#if DEBUG
                _processInterface.ReportError(e.ToString());
#endif
            }
        }

        public Queue<IHookData> Queue { get; set; }
    }
}
